<?php

namespace app\index\service;

use app\common\model\Member;
use app\index\dao\MemberDao;
use app\index\dao\TempTokenDao;
use app\index\traits\SessionAfterLocationTrait;
use app\index\traits\SessionTrait;
use app\index\traits\TempTokenCheckTrait;
use ShidianUtil\Captcha\Captcha;
use ShidianUtil\Utils\CheckUtil;
use think\exception\ValidateException;

/**
 * 手机号登录
 * @package app\session\service
 */
class SessionPhoneService extends AbstractSessionService
{
    use SessionTrait;
    use SessionAfterLocationTrait;
    use TempTokenCheckTrait;

    private MemberService $memberService;
    private MemberDao $memberDao;
    private Captcha $captcha;
    private TempTokenDao $tempTokenDao;

    public function __construct(MemberService $memberService, MemberDao $memberDao, Captcha $captcha, TempTokenDao $tempTokenDao)
    {
        $this->memberService = $memberService;
        $this->memberDao = $memberDao;
        $this->captcha = $captcha;
        $this->tempTokenDao = $tempTokenDao;
    }

    /**
     * 网页手机号验证码登录
     * @param $params
     * @return Member
     */
    public function login($params): Member
    {
        $phone = $params['phone'] ?? null;
        $inviteCode = $params['inviteCode'] ?? '';

        $pf = $params['pf'];
        $chain = $params['chain'];
        $promotionGroupId = $params['promotionGroupId'];

        if (is_blank($phone) || !CheckUtil::isPhoneNumber($phone)) {
            throw new ValidateException('请输入手机号码');
        }

        // 检查律师认证资料
        $this->checkMemberDraft($params['memberDraft'] ?? null);

        // 用户信息字段
        $memberParamsKeys = ['phone', 'inviteCode'];

        // 传进来的用户信息参数
        $memberParams = collect_params($params, $memberParamsKeys);

        // 注册方式: 0/其它,1/qq,2/支付宝,3/微信pc扫码,4/微信小程序,5/微信公众号关注,6/苹果App,7/安卓App,8/百度小程序,9/抖音小程序,
        // 10 h5落地页-手机号验证码
        $memberParams['channel'] = 10;
        $memberParams['pf'] = $pf;
        $memberParams['chain'] = $chain;
        $memberParams['promotionGroupId'] = $promotionGroupId;

        // 查询用户
        $member = $this->findAndAddMemberByPhone($phone, $memberParams);

        // 是否冻结
        $this->checkMemberStatus($member);

        // 提交律师认证资料
        $this->saveMemberDraft($member,$params['memberDraft'] ?? null,  $pf, $chain, $promotionGroupId);

        // **************** 登录并返回 ****************

        // 设置定位
        $this->setLocation($member);

        // 查询前端用户信息
        $member = $this->memberDao->findByLogin($member->id);

        // 刷新token令牌
        $token = $this->getMemberTokenService()->add($member->id, $memberParams['channel'], 3);

        // 给前端的参数，包装一下
        $this->wrapToken($member, $token);

        // 生成tempToken
        $tempToken = $this->encodeTempToken($phone, $inviteCode);

        $member->tempToken = $tempToken;

        $data = [
            'phone' => $phone,
            'inviteCode' => $inviteCode,
            'tempToken' => $tempToken,
            'pf' => $pf,
            'chain' => $chain,
            'promotionGroupId' => $promotionGroupId,
        ];
        $this->tempTokenDao->insertActive($data);

        return $member;
    }

    /**
     * @param string $phone 手机号
     * @param array $memberParams 用户信息
     * @return Member
     */
    private function findAndAddMemberByPhone($phone, array $memberParams)
    {
        $member = Member::where('phone', $phone)
            ->whereIn('status', [0, 1])
            ->order('id', 'ASC')
            ->find();

        if (is_null($member)) {
            // 手机号 未注册

            // 注册新用户账号 && 绑定第三方信息
            $member = $this->getMemberService()->add($memberParams);

        }

        return $member;
    }

    private function getMemberTokenService(): MemberTokenService
    {
        return app(MemberTokenService::class);
    }
}
